package com.s7.widget.widget;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

import com.s7.widget.attr.DashboardAttr;
import com.s7.widget.listener.OnDashBoardListener;

import java.util.ArrayList;
import java.util.List;

/**
 * 自定义仪表盘
 */
public class DashBoard extends View {

    // 获取设置的值
    private DashboardAttr dashBoardAttr;

    // 是否允许拖动
    private boolean isDragging = true;

    // 记录指示器位置
    Point point = new Point();
    // 记录手势抬起前最后一个有效经纬度
    private  float oldX, oldY;
    // 是否取整
    private boolean isTrunc = true;
    //判断是否按下
    private boolean isDown = false;

    // 控件的宽、高
    private int mWidth, mHeight;

    // 进度圆弧起始颜色
    private int startColor, endColor;
    // 进度条颜色
    private Paint paintProgress;
    // 进度条指示器
    private Paint paintIndicator;
    // 进度条指示器阴影
    private Paint paintIndicatorOut;
    private int indicatorColor;
    // 进度弧的宽度
    private int progressWidth;
    // 进度条偏移量
    private int OFFSET = 30;
    // 进度条起点度数
    private int START_ARC;
    // 进度条总占角度
    private int DURING_ARC;
    // 进度条位置
    private RectF rectF;

    // 当前值
    private float mCurrent = 0;
    // 起始值
    private float mStart;
    // 结束值
    private float mEnd;
    // 每一个刻度的间隔 (mEnd - mStart) / mCount
    private float mCountSpace;
    // 总刻度个数
    private int mCountSum;
    // 刻度个数
    private int mCount;
    // 刻度间隔数
    private int mCountGroup;
    // 刻度文字显示规则
    private int mCountRule;
    // 刻度文字显示规则(显示 0:全部; 1:间隔1个; 2间隔两个)
    public static final int INTERVAL = 0;
    public static final int INTERVAL_EVEN = 1;
    public static final int INTERVAL_ODD = 2;
    // 记录刻度值
    private List<Float> mCountArray = null;

    // 单位
    private String mUnit;

    // 背景阴影
    private Paint paintBackgroundOut;
    // 背景
    private Paint paintBackground;
    //背景颜色
    private int backgroundColor;

    //中心圆点的半径
    private int mCenterCircleRadius;
    // 内圆
    private Paint paintCenterCircle;
    private int centerCircleColor;

    // 刻度的Y轴坐标
    private int mScaleY;
    // 刻度
    private Paint paintScale;
    // 刻度值
    private Paint paintScaleStr;

    //字体颜色
    private int textColor;
    // 字体大小
    private int textSize;

    // 当前刻度
    private Paint paintText;
    // 单位
    private Paint paintUnit;

    // 动画
    private ValueAnimator mAnimator;

    private OnDashBoardListener mListener;

    public DashBoard(Context context) {
        this(context, null);
    }

    public DashBoard(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DashBoard(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        dashBoardAttr = new DashboardAttr(context, attrs, defStyleAttr);
        initAttr();
        initPaint();
    }

    private void initAttr() {
        isDragging = dashBoardAttr.isDragging();
        isTrunc = dashBoardAttr.isTrunc();
        mStart = dashBoardAttr.getStart();
        mEnd = dashBoardAttr.getEnd();
        startColor = dashBoardAttr.getStartColor();
        endColor = dashBoardAttr.getEndColor();
        progressWidth = dashBoardAttr.getProgressWidth();
        DURING_ARC = dashBoardAttr.getDuringArc();
        indicatorColor = dashBoardAttr.getIndicatorColor();
        mCount = dashBoardAttr.getCount();
        mCountGroup = dashBoardAttr.getCountGroup();
        mCountRule = dashBoardAttr.getCountRule();
        mUnit = dashBoardAttr.getUnit();
        backgroundColor = dashBoardAttr.getBackgroundColor();
        centerCircleColor = dashBoardAttr.getCenterCircleColor();
        textColor = dashBoardAttr.getTextColor();
        textSize = getSize(dashBoardAttr.getTextSize());
    }

    private int getSize(float size) {
        DisplayMetrics dm = getResources().getDisplayMetrics();
        float value = dm.scaledDensity;
        return (int) (size * value);
    }

    /**
     * 初始化画笔
     */
    private void initPaint() {
        paintBackgroundOut = new Paint();
        paintBackgroundOut.setAntiAlias(true);
        paintBackgroundOut.setStyle(Paint.Style.STROKE);
        paintBackgroundOut.setStrokeWidth(2);
        paintBackgroundOut.setColor(0xFFDFDFDF);
        paintBackgroundOut.setDither(true);

        paintBackground = new Paint();
        paintBackground.setAntiAlias(true);
        paintBackground.setStyle(Paint.Style.FILL);
        paintBackground.setStrokeWidth(2);
        paintBackground.setDither(true);

        paintProgress = new Paint();
        paintProgress.setAntiAlias(true);
        paintProgress.setStrokeWidth(progressWidth);
        paintProgress.setStyle(Paint.Style.STROKE);
        paintProgress.setStrokeCap(Paint.Cap.ROUND);
        paintProgress.setDither(true);

        paintIndicator = new Paint();
        paintIndicator.setAntiAlias(true);
        paintIndicator.setStyle(Paint.Style.FILL);//实心画笔
        paintIndicator.setDither(true);
        paintIndicator.setColor(indicatorColor);

        paintIndicatorOut = new Paint();
        paintIndicatorOut.setAntiAlias(true);
        paintIndicatorOut.setStyle(Paint.Style.STROKE);
        paintIndicatorOut.setStrokeWidth(2);
        paintIndicatorOut.setColor(0xFFDFDFDF);
        paintIndicatorOut.setDither(true);

        paintCenterCircle = new Paint();
        paintCenterCircle.setAntiAlias(true);
        paintCenterCircle.setStyle(Paint.Style.FILL);//实心画笔
        paintCenterCircle.setDither(true);
        paintCenterCircle.setColor(centerCircleColor);

        paintScale = new Paint();
        paintScale.setAntiAlias(true);
        paintScale.setColor(textColor);
        paintScale.setStrokeWidth(3);
        paintScale.setStyle(Paint.Style.FILL);
        paintScale.setDither(true);

        paintScaleStr = new Paint();
        paintScaleStr.setAntiAlias(true);
        paintScaleStr.setStyle(Paint.Style.FILL);
        paintScaleStr.setTextAlign(Paint.Align.LEFT);
        paintScaleStr.setColor(textColor);
        paintScaleStr.setTextSize(22);

        paintText = new Paint();
        paintText.setAntiAlias(true);
        paintText.setStyle(Paint.Style.FILL);
        paintText.setTextAlign(Paint.Align.LEFT);
        paintText.setColor(textColor);
        paintText.setTextSize(textSize);

        paintUnit = new Paint();
        paintUnit.setAntiAlias(true);
        paintUnit.setStyle(Paint.Style.FILL);
        paintUnit.setTextAlign(Paint.Align.LEFT);
        paintUnit.setColor(textColor);
        paintUnit.setTextSize(textSize / 3);
    }

    /**
     * 初始进度条颜色
     */
    private void initShader() {
        updateOval();
        if (startColor != 0 && endColor != 0) {
            SweepGradient shader = new SweepGradient(0, 0,
                    new int[]{startColor, startColor,  endColor, endColor}, null);
            float rotate = 90f;
            Matrix gradientMatrix = new Matrix();
            gradientMatrix.preRotate(rotate, 0, 0);
            shader.setLocalMatrix(gradientMatrix);
            paintProgress.setShader(shader);
        }
    }

    /**
     * 更新进度条位置
     */
    private void updateOval() {
        rectF = new RectF((- mWidth / 2) + OFFSET,
                - (mHeight / 2) + OFFSET,
                (mWidth / 2) - OFFSET,
                (mWidth / 2) - OFFSET);
        // 计算进度条起始点
        START_ARC = 90 + ((360 - DURING_ARC) >> 1);
    }

    /**
     * 通过仪表盘终始值及刻度个数计算仪表盘上显示的个数
     */
    private void initCountArray() {
        if (mCountArray == null) {
            mCountArray = new ArrayList<>();
        }
        mCountArray.clear();
        mCurrent = 0;
        mCountSum = mCount * mCountGroup + 1;
        mCountSpace = (mEnd - mStart) / mCount;
        for (int i=0; i<= mCount; i++) {
            mCountArray.add(mStart + mCountSpace * i);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int specSize = MeasureSpec.getSize(Math.min(widthMeasureSpec, heightMeasureSpec));
        // 处理成正方形
        setMeasuredDimension(specSize, specSize);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // 控件宽、高
        mWidth = Math.min(h, w);
        mHeight = Math.min(h, w);
        // mCenterCircleRadius = mWidth / 2 - OFFSET - progressWidth;
        mCenterCircleRadius = mWidth / 2 - 2 * OFFSET;
        // int numY = -mHeight / 2 + OFFSET + progressWidth;
        mScaleY = - mWidth / 2 + OFFSET * 2;
        initShader();
        initCountArray();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //  移动坐标原点到中心
        canvas.translate(mWidth / 2, mHeight / 2);
        drawBackground(canvas);
        drawProgress(canvas);
        drawCenter(canvas);
        drawerCount(canvas);
        drawProgressIndicator(canvas);
        drawText(canvas);
    }

    /**
     * 绘制当前刻度
     * @param canvas
     */
    private void drawText(Canvas canvas) {
        String text = String.format("%.0f", mCurrent);
        float textX = getTextLength(paintText, String.valueOf(text)) / 2;
        paintText.setColor(textColor);
        paintText.setTextSize(textSize);
        canvas.drawText(String.valueOf(text), - textX, textSize / 2, paintText);
        if (!TextUtils.isEmpty(mUnit)) {
            paintUnit.setColor(textColor);
            paintUnit.setTextSize(textSize / 3);
            canvas.drawText(mUnit,
                    textX + getTextLength(paintUnit, mUnit) / 2,
                    textSize - textSize / 2, paintUnit);
        }
    }

    /**
     * 绘制内盘上的刻度
     * @param canvas
     */
    private void drawerCount(Canvas canvas) {
        canvas.save(); //记录画布状态
        canvas.rotate(-(180 - START_ARC + 90), 0, 0);
        //n根线，只需要n-1个区间
        float rAngle = DURING_ARC / ((mCountSum - 1) * 1.0f);
        paintScale.setColor(textColor);
        paintScaleStr.setColor(textColor);
        for (int i = 0; i < mCountSum; i++) {
            //记录画布状态
            canvas.save();
            canvas.rotate(rAngle * i, 0, 0);
            if (i == 0 || i % mCountGroup == 0) {
                //画长刻度线
                canvas.drawLine(0, mScaleY + 5, 0, mScaleY + 25, paintScale);
                drawCount(canvas, i);
            } else {
                //画短刻度线
                canvas.drawLine(0, mScaleY + 5, 0, mScaleY + 15, paintScale);
            }
            canvas.restore();
        }
        canvas.restore();

    }

    /**
     * 画刻度上的值
     * @param canvas
     * @param i
     */
    private void drawCount(Canvas canvas, int i) {
        if (mCountArray.size() > (i % mCountGroup)) {
            if (mCountRule == INTERVAL_EVEN) {
                if (i / mCountGroup % 2 == 0) {
                    drawCountRule(canvas, i);
                }
            } else  if (mCountRule == INTERVAL_ODD) {
                if (i / mCountGroup % 3 == 0) {
                    drawCountRule(canvas, i);
                } else {
                    if (i / mCountGroup == mCountArray.size() - 1) {
                        drawCountRule(canvas, i);
                    }
                }
            } else {
                drawCountRule(canvas, i);
            }
        }
    }

    /**
     * 画刻度上的值
     * @param canvas
     * @param i
     */
    private void drawCountRule(Canvas canvas, int i) {
        String text = String.format("%.0f", (mCountArray.get(i / mCountGroup)));
        Paint.FontMetricsInt fontMetrics = paintScaleStr.getFontMetricsInt();
        int baseline = ((mScaleY + 40) + (fontMetrics.bottom - fontMetrics.top) / 2);
        canvas.drawText(text, - getTextLength(paintScaleStr, text) / 2, baseline, paintScaleStr);
    }

    /**
     * 获取指定字符串长度
     * @param paint
     * @param text
     * @return
     */
    private float getTextLength(Paint paint, String text) {
        if (TextUtils.isEmpty(text)) return 0;
        float textLength = paint.measureText(text);
        return textLength;
    }

    /**
     * 绘制内圆
     * @param canvas
     */
    private void drawCenter(Canvas canvas) {
        paintCenterCircle.setColor(centerCircleColor);
        canvas.drawCircle(0, 0, mCenterCircleRadius, paintCenterCircle);
    }

    /**
     * 绘制进度条上的指示器
     * @param canvas
     */
    private void drawProgressIndicator(Canvas canvas) {
        float progressRadians = getSweep();
        float thumbX = ((mWidth / 2) - OFFSET) * (float) Math.sin(progressRadians);
        float thumbY = ((mHeight / 2) - OFFSET) * (float) Math.cos(progressRadians);
        point.x = (int) thumbX;
        point.y = (int) thumbY;
        canvas.drawCircle(thumbX, thumbY, progressWidth + 1, paintIndicatorOut);
        paintIndicator.setColor(indicatorColor);
        canvas.drawCircle(thumbX, thumbY, progressWidth, paintIndicator);
    }

    /**
     * 绘制进度圆弧
     * @param canvas
     */
    private void drawProgress(Canvas canvas) {
        canvas.drawArc(rectF, START_ARC, DURING_ARC, false, paintProgress);
    }

    /**
     * 绘制仪表盘背景
     * @param canvas
     */
    private void drawBackground(Canvas canvas) {
        //最外阴影
        canvas.drawCircle(0, 0, mWidth / 2 - 2, paintBackgroundOut);
        canvas.save();
        //背景
        if (backgroundColor != 0) {
            paintBackground.setColor(backgroundColor);
            canvas.drawCircle(0, 0, mWidth / 2 - 4, paintBackground);
        }
    }

    /**
     * 获取指示器当前所在角度 (未划过的角度)
     * @return
     */
    private float getSweep() {
        /**
         * 获取当前值所占的百分比
         */
        float proportion = DURING_ARC * ((mEnd - mStart - (mCurrent - mStart)) / (mEnd - mStart));
        return (float) (((360.0f - DURING_ARC) / 2 + proportion) / 180 * Math.PI);
    }

    /**
     * 设置选中回调事件
     * @param listener
     */
    public void setOnListener(OnDashBoardListener listener) {
        this.mListener = listener;
    }

    /**
     * 设置是否允许进度条拖动
     * @param dragging
     */
    public DashBoard setDragging(boolean dragging) {
        isDragging = dragging;
        return this;
    }

    /**
     * 设置是否取整（取已有刻度）
     * @param trunc
     */
    public DashBoard setTrunc(boolean trunc) {
        isTrunc = trunc;
        return this;
    }

    /**
     * 设置当前值
     * @param current
     */
    public void setCurrent(float current) {
        setAnimator(current);
    }

    /**
     * 设置仪表盘刻度
     * @param start 起始值
     * @param end 结束值
     * @param unit 单位
     */
    public DashBoard setDividingRule(float start, float end, String unit) {
        return setDividingRule(start, end, mCount, mCountGroup, unit);
    }

    /**
     * 设置仪表盘刻度
     * @param start 起始值
     * @param end 结束值
     * @param count 刻度个数
     * @param unit 单位
     */
    public DashBoard setDividingRule(float start, float end, int count, String unit) {
        return setDividingRule(start, end, count, mCountGroup, unit);
    }

    /**
     * 设置仪表盘刻度
     * @param start 起始值
     * @param end 结束值
     * @param count 刻度个数
     * @param countGroup 刻度间隔
     * @param unit 单位
     */
    public DashBoard setDividingRule(float start, float end, int count, int countGroup, String unit) {
        this.mStart = start;
        this.mEnd = end;
        this.mCount=count;
        this.mUnit = unit;
        this.mCountGroup = countGroup;
        return setDividingRule(start, end, count, mCountGroup, mCountRule, unit);
    }

    /**
     * 设置仪表盘刻度
     * @param start 起始值
     * @param end 结束值
     * @param count 刻度个数
     * @param countGroup 刻度间隔
     * @param countRule 刻度值显示规则
     * @param unit 单位
     */
    public DashBoard setDividingRule(float start, float end, int count, int countGroup, int countRule, String unit) {
        this.mStart = start;
        this.mEnd = end;
        this.mCount=count;
        this.mUnit = unit;
        this.mCountGroup = countGroup;
        this.mCountRule = countRule;
        initShader();
        initCountArray();
        invalidate();
        return this;
    }

    /**
     * 设置仪表盘进度条颜色
     * @param startColor 开始
     * @param endColor 结束
     */
    public DashBoard setProgress(int startColor, int endColor) {
        return setProgress(startColor, endColor, progressWidth);
    }

    /**
     * 设置仪表盘进度条颜色
     * @param startColor 开始
     * @param endColor 结束
     * @param width 进度条宽度
     */
    public DashBoard setProgress(int startColor, int endColor, int width) {
        this.startColor = startColor;
        this.endColor = endColor;
        this.progressWidth = width;
        return setProgress(startColor, endColor, width, DURING_ARC);
    }

    /**
     * 设置仪表盘进度条颜色
     * @param startColor 开始
     * @param endColor 结束
     * @param width 进度条宽度
     * @param duringArc 进度条总占角度
     */
    public DashBoard setProgress(int startColor, int endColor, int width, int duringArc) {
        this.startColor = startColor;
        this.endColor = endColor;
        this.progressWidth = width;
        this.DURING_ARC = duringArc;
        initShader();
        initCountArray();
        invalidate();
        return this;
    }

    /**
     * 设置指示器颜色
     * @param indicatorColor
     */
    public DashBoard setIndicatorColor(int indicatorColor) {
        this.indicatorColor = indicatorColor;
        invalidate();
        return this;
    }

    public DashBoard setBackground(int backgroundColor) {
        this.backgroundColor = backgroundColor;
        invalidate();
        return this;
    }

    public DashBoard setCenterCircleColor(int centerCircleColor) {
        this.centerCircleColor = centerCircleColor;
        invalidate();
        return this;
    }

    public DashBoard setTextColor(int textColor) {
        this.textColor = textColor;
        invalidate();
        return this;
    }

    public DashBoard setTextSize(int textSize) {
        this.textSize = textSize;
        invalidate();
        return this;
    }

    private void setAnimator(final float current) {
        if (mAnimator != null && mAnimator.isRunning()) {
            mAnimator.cancel();
        }
        long time = (long) (Math.abs(current - mCurrent) / (mEnd - mStart) * 2000);
        mAnimator = ValueAnimator.ofFloat(mCurrent, current);
        mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mCurrent = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        mAnimator.setRepeatMode(ValueAnimator.REVERSE);
//        mAnimator.setRepeatCount(ValueAnimator.REVERSE);
        mAnimator.setDuration(time);
        mAnimator.start();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isDragging) {
            return super.onTouchEvent(event);
        }
       // 处理拖动事件
        float currentX = event.getX();
        float currentY = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (isNearProgress(currentX, currentY) && isNearIndicator(currentX, currentY)) {
                    oldX = currentX;
                    oldY = currentY;
                    isDown = true;
                }
                if (isNearProgress(currentX, currentY)) {
                    oldX = currentX;
                    oldY = currentY;
                    isDown = true;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (isNearProgress(currentX, currentY) && isNearIndicator(currentX, currentY)) {
                    if (isDown) {
                        oldX = currentX;
                        oldY = currentY;
                        mCurrent = calculateAngle(currentX, currentY);
                        if (mCurrent < 0) {
                            mCurrent = 0;
                        }
                        if (mCurrent > mEnd) {
                            mCurrent = mEnd;
                        }

                        invalidate();
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                if (isDown) {
                    getTrunc(calculateAngle(oldX, oldY));
                }
                isDown = false;
                break;
        }
        return true;
    }

    /**
     * 根据坐标，计算相对进度条的角度，进而求出当前值
     * @param x
     * @param y
     */
    private float calculateAngle(float x, float y) {
        float degrees;
        /**
         * 判断 点 是否在圆心的右边
         */
        if (x >= mWidth / 2) {
            degrees = ((float) (DURING_ARC + 60 - 180 * (Math.atan2(x - mWidth / 2, y -  mHeight / 2)) / Math.PI));
        } else {
            degrees = ((float) (- 60 + 180 * (Math.atan2(mWidth / 2 - x, y - mHeight / 2)) / Math.PI));
        }
        return (mEnd - mStart) * degrees / DURING_ARC;

    }

    /**
     * 是否根据当前值提取最近刻度值
     */
    private void getTrunc(float current) {
        if (isTrunc) {
            int num = (int) (current / mCountSpace);
            if (current % mCountSpace >= mCountSpace / 2) {
                current = mCountArray.get(num + 1);
            } else {
                current = mCountArray.get(num);
            }
        }
        if (mListener != null) {
            mListener.onDashBoard(this, current);
        }
        setAnimator(current);
    }

    /**
     * 判断进度条是否被触摸
     * @param x
     * @param y
     * @return
     */
    private boolean isNearProgress(float x, float y) {
        // 距离圆心的距离
        float distance = (float) Math.sqrt(Math.pow((mWidth / 2 - x), 2) + Math.pow((mHeight / 2 - y), 2));
       // 计算进度条内边界线
        int bounds = mWidth / 2 - OFFSET - progressWidth / 2 - 15;
        // 计算进度条外边界线
        int boundsOut = mWidth / 2 - OFFSET + progressWidth / 2 + 15;
        if (distance < boundsOut && distance > bounds) {
            // 判断坐标Y是否超出范围（calculate4Y(START_ARC) 求出进度条坐标Y的极限）
            if (y <= calculate4Y(START_ARC)) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    /**
     * 判断指示器是否被触摸
     * @param x
     * @param y
     * @return
     */
    private boolean isNearIndicator(float x, float y) {
        return getCircleX(x) < point.x + progressWidth + 10
                && getCircleX(x) > point.x - progressWidth - 10
                && getCircleY(y) < point.y + progressWidth + 10
                && getCircleY(y) > point.y - progressWidth - 10;
    }

    /**
     * View X轴坐标 转 圆X轴坐标
     * @param x
     * @return
     */
    private float getCircleX(float x) {
        if (x > mWidth / 2) {
            return x - mWidth / 2;
        } else if(x < mWidth / 2) {
           return - mWidth / 2 + x;
        }
        return 0;
    }

    /**
     * View Y轴坐标 转 圆Y轴坐标
     * @param y
     * @return
     */
    private float getCircleY(float y) {
        if (y > mHeight / 2) {
           return y - mHeight / 2;
        } else if(y < mHeight / 2) {
            return - mHeight / 2 + y;
        }
        return 0;
    }

    /**
     * 根据半径和角度计算x坐标
     */
    private float calculateX(float r, double angle) {
        angle = angle * ((2 * Math.PI) / 360);
        double x = r * Math.sin(angle);
        double xFinal = mWidth / 2 + x;
        return (float) xFinal;
    }

    /**
     * 根据半径和角度计算y坐标
     */
    private float calculateY(float r, double angle) {
        angle = angle * ((2 * Math.PI) / 360);
        double y = r * Math.cos(angle);
        double yFinal = mHeight / 2 - y;
        return (float) yFinal;
    }

    /**
     * 根据半径和角度计算x坐标
     */
    private float calculate4X(double angle) {
        angle = angle * Math.PI / 180;
        double x = (mWidth / 2 - OFFSET - progressWidth / 2 + progressWidth) * Math.cos(angle);
        double xFinal = mWidth / 2 + x;
        return (float) xFinal;
    }

    /**
     * 根据半径和角度计算y坐标
     */
    private float calculate4Y(double angle) {
        angle = angle * Math.PI / 180;
        double y = (mWidth / 2 - OFFSET - progressWidth / 2 + progressWidth) * Math.sin(angle);
        double yFinal = mHeight / 2 + y;
        return (float) yFinal;
    }
}
